package cn.turboinfo.fuyang.api.domain.mini.usecase.shop;

import cn.turboinfo.fuyang.api.domain.common.handler.shop.ShopDataFactory;
import cn.turboinfo.fuyang.api.domain.common.handler.staff.StaffDataFactory;
import cn.turboinfo.fuyang.api.domain.common.service.category.CategoryService;
import cn.turboinfo.fuyang.api.domain.common.service.file.FileAttachmentService;
import cn.turboinfo.fuyang.api.domain.common.service.product.ProductService;
import cn.turboinfo.fuyang.api.domain.common.service.shop.HousekeepingShopService;
import cn.turboinfo.fuyang.api.domain.common.service.staff.HousekeepingStaffService;
import cn.turboinfo.fuyang.api.domain.common.usecase.AbstractUseCase;
import cn.turboinfo.fuyang.api.domain.util.IdCardUtils;
import cn.turboinfo.fuyang.api.domain.web.component.file.FileRefTypeConstant;
import cn.turboinfo.fuyang.api.entity.common.enumeration.staff.StaffStatus;
import cn.turboinfo.fuyang.api.entity.common.fo.shop.ViewShopFO;
import cn.turboinfo.fuyang.api.entity.common.fo.staff.ViewStaffFO;
import cn.turboinfo.fuyang.api.entity.common.pojo.category.Category;
import cn.turboinfo.fuyang.api.entity.common.pojo.file.FileAttachment;
import cn.turboinfo.fuyang.api.entity.common.pojo.product.Product;
import cn.turboinfo.fuyang.api.entity.common.pojo.staff.HousekeepingStaff;
import cn.turboinfo.fuyang.api.entity.mini.fo.shop.MiniShop;
import com.google.common.collect.Lists;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.qbean.helper.component.mapper.BeanMapper;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 查看门店详情
 *
 * @author gadzs
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class MiniViewShopUseCase extends AbstractUseCase<MiniViewShopUseCase.InputData, MiniViewShopUseCase.OutputData> {

    private final HousekeepingShopService housekeepingShopService;
    private final HousekeepingStaffService housekeepingStaffService;
    private final CategoryService categoryService;
    private final ProductService productService;
    private final FileAttachmentService fileAttachmentService;

    private final StaffDataFactory staffDataFactory;

    private final ShopDataFactory shopDataFactory;

    @Override
    protected OutputData doAction(InputData inputData) {
        MiniShop miniShop = new MiniShop();
        val shopId = inputData.getId();
        val shop = housekeepingShopService.getByIdEnsure(shopId);

        // 设置图片编码列表
        shop.setImgList(fileAttachmentService
                .findByRefIdAndRefType(shopId, FileRefTypeConstant.SHOP_IMG)
                .stream()
                .map(FileAttachment::getId)
                .collect(Collectors.toList()));

        shopDataFactory.maskInfo(shop);
        miniShop.setShop(BeanMapper.map(shop, ViewShopFO.class));

        Long companyId = shop.getCompanyId();
        if (companyId != null) {

            // 家政员
            List<HousekeepingStaff> staffList = housekeepingStaffService.findByCompanyId(companyId)
                    .stream()
                    .filter(staff -> staff.getStatus().equals(StaffStatus.PUBLISHED))
                    .toList();

            miniShop.setStaffNum(Long.parseLong(String.valueOf(staffList.size())));

            // 填充省份名称
            staffDataFactory.assembleCityName(staffList);

            miniShop.setStaffList(staffList.subList(0, Math.min(staffList.size(), 3))
                    .stream()
                    .map(staff -> {

                        staff.setAge(IdCardUtils.countAge(staff.getIdCard()));

                        if (staff.getDisplayName().isBlank()) {
                            staff.setDisplayName(staff.getName());
                        }

                        staffDataFactory.maskInfo(staff);
                        return BeanMapper.map(staff, ViewStaffFO.class);
                    })
                    .toList()
            );

            // 服务分类
            List<Product> productList = productService.findByShopIdCollection(Lists.newArrayList(shopId));
            Map<Long, Long> productMap = productList.stream().collect(Collectors.groupingBy(Product::getCategoryId, Collectors.counting()));

            val categoryList = categoryService.findByIdCollection(productMap.keySet());

            Set<Long> categoryIdSet = categoryList.stream()
                    .map(Category::getId)
                    .collect(Collectors.toSet());

            Map<Long, Long> fileMap = fileAttachmentService.findByRefIdInAndRefType(categoryIdSet, FileRefTypeConstant.CATEGORY_ICON)
                    .stream()
                    .collect(Collectors.toMap(FileAttachment::getRefId, FileAttachment::getId));

            categoryList.forEach(category -> {
                if (fileMap.containsKey(category.getId())) {
                    category.setIconId((fileMap.get(category.getId())));
                }
            });

            miniShop.setProductNum(Long.parseLong(String.valueOf(productList.size())));
            miniShop.setCategoryList(categoryList.subList(0, Math.min(categoryList.size(), 4)));
        }

        return OutputData.builder()
                .miniShop(miniShop)
                .build();
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class InputData extends AbstractUseCase.InputData {

        /**
         * 门店id
         */
        @NotNull(
                message = "门店id不能为空"
        )
        private Long id;

    }

    @Getter
    @Setter
    @Builder
    public static class OutputData extends AbstractUseCase.OutputData {

        private MiniShop miniShop;
    }
}
